package com.zone.core.helper

import android.Manifest
import android.content.ContentResolver
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.DocumentsContract
import com.zone.core.CoreApplication
import org.jetbrains.anko.toast
import java.io.File
import java.io.IOException
import java.io.OutputStreamWriter

object FileHelper {
    private val context = CoreApplication.coreApp

    enum class WriteMode {
        OVERWRITE, APPEND
    }

    enum class ExternalStorageDirectory(val path: String) {
        DOWNLOADS("primary:Download"), DCIM("primary:DCIM"),//照片、视频
        MOVIES("primary:Movies"),//电影
        MUSIC("primary:Music"),//音乐
        PICTURES("primary:Pictures"),//图片
        DOCUMENTS("primary:Documents");//文档

        fun toUri(fileName: String): Uri {
            return DocumentsContract.buildDocumentUri(
                "com.android.externalstorage.documents", "$path"
            )
        }
    }

    enum class MimeType(val value: String) {
        /**
         * 纯文本文件
         */
        TEXT_PLAIN("text/plain"),

        /**
         * 超文本标记语言文件
         */
        TEXT_HTML("text/html"),

        /**
         * 层叠样式表文件
         */
        TEXT_CSS("text/css"),

        /**
         * 可扩展标记语言文件
         */
        TEXT_XML("text/xml"),

        /**
         * 逗号分隔值文件
         */
        TEXT_CSV("text/csv"),

        /**
         * JPEG图像文件
         */
        IMAGE_JPEG("image/jpeg"),

        /**
         * PNG图像文件
         */
        IMAGE_PNG("image/png"),

        /**
         * GIF图像文件
         */
        IMAGE_GIF("image/gif"),

        /**
         * TIFF图像文件
         */
        IMAGE_TIFF("image/tiff"),

        /**
         * BMP图像文件
         */
        IMAGE_BMP("image/bmp"),

        /**
         * MP3音频文件
         */
        AUDIO_MPEG("audio/mpeg"),

        /**
         * WAV音频文件
         */
        AUDIO_WAV("audio/wav"),

        /**
         * AAC音频文件
         */
        AUDIO_AAC("audio/aac"),

        /**
         * FLAC音频文件
         */
        AUDIO_FLAC("audio/flac"),

        /**
         * MP4视频文件
         */
        VIDEO_MP4("video/mp4"),

        /**
         * QuickTime视频文件
         */
        VIDEO_QUICKTIME("video/quicktime"),

        /**
         * Matroska视频文件
         */
        VIDEO_MATROSKA("video/x-matroska"),

        /**
         * PDF文档
         */
        APPLICATION_PDF("application/pdf"),

        /**
         * Microsoft Word文档
         */
        APPLICATION_MSWORD("application/msword"),

        /**
         * Microsoft Excel文档
         */
        APPLICATION_VND_MS_EXCEL("application/vnd.ms-excel"),

        /**
         * Microsoft PowerPoint文档
         */
        APPLICATION_VND_MS_POWERPOINT("application/vnd.ms-powerpoint"),

        /**
         * ZIP压缩文件
         */
        APPLICATION_ZIP("application/zip");

    }

    //写入内部文件
    fun writeInternalFile(fileName: String, content: String) {
        val file = File(context.filesDir, fileName)
        try {
            if (!file.exists()) {
                file.createNewFile()
            }
            val outputStreamWriter = OutputStreamWriter(file.outputStream())
            outputStreamWriter.write(content)
            outputStreamWriter.flush()
            outputStreamWriter.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    //读取内部文件
    fun readInternalFile(fileName: String): String {
        val file = File(context.filesDir, fileName)
        return if (file.exists()) {
            file.readText()
        } else {
            ""
        }
    }

    //写入外部私有目录
    fun writeDataToExternalStorage(
        fileName: String,
        content: String,
        writeMode: WriteMode = WriteMode.OVERWRITE,
        externalStorageDirectory: ExternalStorageDirectory? = null
    ) {
        val file = File(context.getExternalFilesDir(externalStorageDirectory?.path), fileName)
        try {
            if (!file.exists()) {
                file.createNewFile()
            }
            val outputStreamWriter = OutputStreamWriter(file.outputStream())
            outputStreamWriter.write(content)
            outputStreamWriter.flush()
            outputStreamWriter.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    //读取外部私有存储内容
    fun readDataFromExternalStorage(
        fileName: String, externalStorageDirectory: ExternalStorageDirectory? = null
    ): String {
        val file = File(context.getExternalFilesDir(externalStorageDirectory?.path), fileName)
        return if (file.exists()) {
            file.readText()
        } else {
            ""
        }
    }

    //获取外部私有存储目录
    fun getExternalStorageFile(): File? {
        if (context.getExternalFilesDir(null) == null) {
            context.toast("外部私有目录获取失败")
            return null
        }
        return context.getExternalFilesDir(null)
    }

    //获取外部公共存储目录
    private fun getExternalPublicStorageFile(): File? {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            /*大于23需要动态申请权限
            <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
             大于29 需要 MANAGE_EXTERNAL_STORAGE*/
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
                if (context.checkSelfPermission(Manifest.permission.MANAGE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    context.toast("操作权限异常")
                }
            }
            //是否有权限
            if (context.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED && context.checkSelfPermission(
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                context.toast("操作权限异常")
                return null
            } else {
                val downloads =
                    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
                if (downloads == null) {
                    context.toast("外部存储获取失败")
                    return null
                }
                return downloads
            }
        }
        //23以下版本
        val externalPublicDir =
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
        if (externalPublicDir == null) {
            context.toast("外部公共目录获取失败")
            return null
        }
        return externalPublicDir
    }

    //写入外部存储目录
    public fun writeDataToExternalPublicStorage(
        fileName: String,
        content: String,
        writeMode: WriteMode = WriteMode.OVERWRITE,
        mimeType: MimeType = MimeType.TEXT_PLAIN,
        rootUri: ExternalStorageDirectory = ExternalStorageDirectory.DOWNLOADS
    ) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
            getExternalPublicStorageFile()?.let {
                val file = File(it.path, fileName)
                try {
                    if (!file.exists()) {
                        file.createNewFile()
                    }
                    val outputStreamWriter = OutputStreamWriter(file.outputStream())
                    outputStreamWriter.write(content)
                    outputStreamWriter.flush()
                    outputStreamWriter.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
            return
        }

        val resolver: ContentResolver = context.contentResolver
        val fileUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            rootUri.toUri(fileName)
        } else {
            context.toast("系统版本过低")
            return
        }
        // Check if the file exists
        val exists = resolver.query(fileUri, null, null, null, null)?.moveToFirst() == true
        // If the file does not exist or we are overwriting it
        if (!exists || writeMode == WriteMode.OVERWRITE) {
            // Delete existing file if it exists and we are overwriting
            if (exists && writeMode == WriteMode.OVERWRITE) {
                resolver.delete(fileUri, null, null)
            }
            // Create new file
            val newFileUri = DocumentsContract.createDocument(
                resolver, rootUri.toUri(fileName), mimeType.value, fileName
            )
            // Write data to the file
            writeToFile(resolver, newFileUri!!, content)
        } else if (writeMode == WriteMode.APPEND) {
            // Append data to the existing file
            writeToFile(resolver, fileUri, content)
        }
    }

    private fun writeToFile(resolver: ContentResolver, uri: Uri, content: String) {
        try {
            OutputStreamWriter(resolver.openOutputStream(uri), "UTF-8").use { writer ->
                writer.write(content)
                writer.flush()
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    //读取外部共有存储目录内容
    fun readDataFromExternalPublicStorage(
        fileName: String,
    ): String? {
        getExternalPublicStorageFile()?.let {
            val file = File(it.path, fileName)
            return if (file.exists()) {
                file.readText()
            } else {
                null
            }
        }
        return null
    }

    //读取外部存储目录
    fun readDataFromFile(
        fileName: String, rootUri: ExternalStorageDirectory = ExternalStorageDirectory.DOWNLOADS
    ): String? {
        val resolver: ContentResolver = context.contentResolver
        val fileUri = rootUri.toUri(fileName)

        // Check if the file exists
        val exists = resolver.query(fileUri, null, null, null, null)?.moveToFirst() ?: false

        if (!exists) {
            // File does not exist
            return null
        }

        // Read data from the file
        return readFromFile(resolver, fileUri)
    }

    private fun readFromFile(resolver: ContentResolver, uri: Uri): String? {
        var result: String? = null
        resolver.openInputStream(uri)?.bufferedReader()?.use { reader ->
            result = reader.readText()
        }
        return result
    }

}